package com.sugar.monitor;

import lombok.extern.slf4j.Slf4j;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadPoolMonitor {

    private final ThreadPoolExecutor executor;
    private final String name;
    private final int intervalSeconds;

    private final ScheduledExecutorService monitorScheduler = Executors.newSingleThreadScheduledExecutor();

    public ThreadPoolMonitor(String name, ExecutorService executor, int intervalSeconds) {
        this.name = name;
        if (!(executor instanceof ThreadPoolExecutor)) {
            throw new IllegalArgumentException("Unsupported executor type");
        }
        this.executor = (ThreadPoolExecutor) executor;
        this.intervalSeconds = intervalSeconds;
    }

    @PostConstruct
    public void start() {
        monitorScheduler.scheduleAtFixedRate(() -> {
            log.info("[ThreadPool Monitor] {} => " +
                            "Active: {}, PoolSize: {}, Core: {}, Max: {}, " +
                            "Queue: {}/{} (remaining: {}), CompletedTasks: {}, TotalTasks: {}",
                    name,
                    executor.getActiveCount(),
                    executor.getPoolSize(),
                    executor.getCorePoolSize(),
                    executor.getMaximumPoolSize(),
                    executor.getQueue().size(),
                    executor.getQueue().remainingCapacity() + executor.getQueue().size(),
                    executor.getQueue().remainingCapacity(),
                    executor.getCompletedTaskCount(),
                    executor.getTaskCount()
            );
        }, 10, intervalSeconds, TimeUnit.SECONDS);
    }

    @PreDestroy
    public void stop() {
        monitorScheduler.shutdownNow();
    }
}

